home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_074 / less / input.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  4KB  |  193 lines

  1. /*
  2.  * High level routines dealing with getting lines of input 
  3.  * from the file being viewed.
  4.  *
  5.  * When we speak of "lines" here, we mean PRINTABLE lines;
  6.  * lines processed with respect to the screen width.
  7.  * We use the term "raw line" to refer to lines simply
  8.  * delimited by newlines; not processed with respect to screen width.
  9.  */
  10.  
  11. #include "less.h"
  12.  
  13. extern int do_bs;
  14. extern int squeeze;
  15. extern char *line;
  16.  
  17. /*
  18.  * Get the next line.
  19.  * A "current" position is passed and a "new" position is returned.
  20.  * The current position is the position of the first character of
  21.  * a line.  The new position is the position of the first character
  22.  * of the NEXT line.  The line obtained is the line starting at curr_pos.
  23.  */
  24.     public POSITION
  25. forw_line(curr_pos)
  26.     POSITION curr_pos;
  27. {
  28.     POSITION new_pos;
  29.     register int c;
  30.  
  31.     if (curr_pos == NULL_POSITION || ch_seek(curr_pos))
  32.         return (NULL_POSITION);
  33.  
  34.     c = ch_forw_get();
  35.     if (c == EOF)
  36.         return (NULL_POSITION);
  37.  
  38.     prewind();
  39.     for (;;)
  40.     {
  41.         if (c == '\n' || c == EOF)
  42.         {
  43.             /*
  44.              * End of the line.
  45.              */
  46.             new_pos = ch_tell();
  47.             break;
  48.         }
  49.  
  50.         /*
  51.          * Append the char to the line and get the next char.
  52.          */
  53.         if (pappend(c))
  54.         {
  55.             /*
  56.              * The char won't fit in the line; the line
  57.              * is too long to print in the screen width.
  58.              * End the line here.
  59.              */
  60.             new_pos = ch_tell() - 1;
  61.             break;
  62.         }
  63.         c = ch_forw_get();
  64.     }
  65.     (void) pappend('\0');
  66.  
  67.     if (squeeze && *line == '\0')
  68.     {
  69.         /*
  70.          * This line is blank.
  71.          * Skip down to the last contiguous blank line
  72.          * and pretend it is the one which we are returning.
  73.          */
  74.         while ((c = ch_forw_get()) == '\n')
  75.             ;
  76.         if (c != EOF)
  77.             (void) ch_back_get();
  78.         new_pos = ch_tell();
  79.     }
  80.  
  81.     return (new_pos);
  82. }
  83.  
  84. /*
  85.  * Get the previous line.
  86.  * A "current" position is passed and a "new" position is returned.
  87.  * The current position is the position of the first character of
  88.  * a line.  The new position is the position of the first character
  89.  * of the PREVIOUS line.  The line obtained is the one starting at new_pos.
  90.  */
  91.     public POSITION
  92. back_line(curr_pos)
  93.     POSITION curr_pos;
  94. {
  95.     POSITION new_pos, begin_new_pos;
  96.     int c;
  97.  
  98.     if (curr_pos == NULL_POSITION || curr_pos <= (POSITION)0 ||
  99.         ch_seek(curr_pos-1))
  100.         return (NULL_POSITION);
  101.  
  102.     if (squeeze)
  103.     {
  104.         /*
  105.          * Find out if the "current" line was blank.
  106.          */
  107.         (void) ch_forw_get();   /* Skip the newline */
  108.         c = ch_forw_get();      /* First char of "current" line */
  109.         (void) ch_back_get();   /* Restore our position */
  110.         (void) ch_back_get();
  111.  
  112.         if (c == '\n')
  113.         {
  114.             /*
  115.              * The "current" line was blank.
  116.              * Skip over any preceeding blank lines,
  117.              * since we skipped them in forw_line().
  118.              */
  119.             while ((c = ch_back_get()) == '\n')
  120.                 ;
  121.             if (c == EOF)
  122.                 return (NULL_POSITION);
  123.             (void) ch_forw_get();
  124.         }
  125.     }
  126.  
  127.     /*
  128.      * Scan backwards until we hit the beginning of the line.
  129.      */
  130.     for (;;)
  131.     {
  132.         c = ch_back_get();
  133.         if (c == '\n')
  134.         {
  135.             /*
  136.              * This is the newline ending the previous line.
  137.              * We have hit the beginning of the line.
  138.              */
  139.             new_pos = ch_tell() + 1;
  140.             break;
  141.         }
  142.         if (c == EOF)
  143.         {
  144.             /*
  145.              * We have hit the beginning of the file.
  146.              * This must be the first line in the file.
  147.              * This must, of course, be the beginning of the line.
  148.              */
  149.             new_pos = (POSITION)0;
  150.             break;
  151.         }
  152.     }
  153.  
  154.     /*
  155.      * Now scan forwards from the beginning of this line.
  156.      * We keep discarding "printable lines" (based on screen width)
  157.      * until we reach the curr_pos.
  158.      *
  159.      * {{ This algorithm is pretty inefficient if the lines
  160.      *    are much longer than the screen width, 
  161.      *    but I don't know of any better way. }}
  162.      */
  163.     if (ch_seek(new_pos))
  164.         return (NULL_POSITION);
  165.     loop:
  166.     begin_new_pos = new_pos;
  167.     prewind();
  168.  
  169.     do
  170.     {
  171.         c = ch_forw_get();
  172.         new_pos++;
  173.         if (c == '\n')
  174.             break;
  175.         if (pappend(c))
  176.         {
  177.             /*
  178.              * Got a full printable line, but we haven't
  179.              * reached our curr_pos yet.  Discard the line
  180.              * and start a new one.
  181.              */
  182.             (void) pappend('\0');
  183.             (void) ch_back_get();
  184.             new_pos--;
  185.             goto loop;
  186.         }
  187.     } while (new_pos < curr_pos);
  188.  
  189.     (void) pappend('\0');
  190.  
  191.     return (begin_new_pos);
  192. }
  193.